let COMMON_FUNS = {

  ['常用函数']: {
    //   AVERAGE(...args) {
    //     /*
    // AVERAGE(number1,number2,…,countstring):返回指定数据的平均值。
    // Number1,number2…:用于计算平均值的参数;
    // countString:文字、逻辑值是否参与计数。
    // 备注:
    // 参数必须是数字，或是含有数字的名称，数组或引用。
    // 如果数组或引用参数中含有文字，逻辑值，默认参与计数，countString为false则不参与计数；空单元格始终不参与计数，但是，单元格中的零值参与。空字符串也会参与计数。
    // 示例:
    // 如果A1:A6被命名为“ages”，分别等于10，23，文字，29，33及25，则:AVERAGE(A1:A6)等于20。
    // AVERAGE(A1:A6,false)等于24。
    // AVERAGE(ages)等于20。
    // 如果还有一个年龄为27的，求所有年龄的平均值为:AVERAGE(A1:A6,27)等于21。
    //      */
    //     return ZY.lodash.mean(...args)
    //   }
//      DATE(year,month,day) {
//        /*
// DATE(year,month,day):返回一个表示某一特定日期的系列数。
// Year:代表年，可为一到四位数。
// Month:
// 代表月份。若month<12，则函数把参数值作为月。若month>12，则函数从年的一月份开始往上累加。
// 例如:DATE(2000,25,2)等于2002年1月2日的系列数。
// Day:
// 代表日。若日期小于等于某指定月的天数，则函数将此参数值作为日。若日期大于某指定月的天数，则函数从指定月份的第一天开始往上累加。若日期大于两个或多个月的总天数，则函数把减去两个月或多个月的余数加到第三或第四个月上，依此类推。
// 例如:DATE(2000,3,35)等于2000年4月4日的系列数。
// 备注:
// 若需要处理公式中日期的一部分，如年或月等，则可用此公式。若年，月和日是函数而不是函数中的常量，则此公式最能体现其作用。
// 示例:
// DATE(1978,9,19)等于1978-09-19.
// DATE(1211,12,1)等于1211-12-01.
//         */
//      }
    SUM(...args) {
      /*
SUM(number1,number2,…):求一个指定单元格区域中所有数字之和。
Number1,number2,…:1到n个参数或指定单元格区域中所有数字。
备注:
函数将直接键入参数中的数值、逻辑值及文本表达式计算在内。若参数是数组或引用，则只有数组或单元格引用中的数值进行计算。
示例:
SUM(70,80)等于150。
SUM("70",80,TRUE)等于151，逻辑值“TRUE”作为1来计算；“FALSE”作为0计算；文本“70”作为70来计算。
       */
      return ZY.lodash.sum(args)
    },
    RANGE(from,to,step) {
      /*
RANGE(from,to,step)函数表示从整数from开始，以step为每一步的大小，直到整数to的一个数字序列。
例如：
RANGE(1,5,1)表示从1开始，直到5(包括5)，每一步大小为1，那么它返回一个数字序列为[1,2,3,4,5]。
RANGE(-1,6,2)表示从-1开始，直到6(包括6)，每一步大小为2，那么它返回一个数字序列为[-1,1,3,5]。
备注：RANGE函数有三种参数形式：
1. RANGE(to)，默认的from为1，step为1，例如：RANGE(4)返回[1,2,3,4]。RANGE(-5)返回[]。
2. RANGE(from,to)，默认的step为1，例如:RANGE(-1,3)返回[-1,0,1,2,3]。RANGE(0,5)返回[0,1,2,3,4,5]。
3. RANGE(from,to,step)，三个参数的情况参照上面的注释，例如：RANGE(6,-1,-2)返回[6,4,2,0]。RANGE(4,1,1)返回[]。
       */
      return _.range( start, end, step )
    }
  },
  ['文本函数']: {
    CHAR(number) {
      /*
CHAR(number):根据指定数字返回对应的字符。CHAR函数可将计算机其他类型的数字代码转换为字符。
Number:用于指定字符的数字，介于1~65535之间（包括1和65535）。
示例:
CHAR(88)等于“X”。
CHAR(45)等于“-”。
       */
      return String.fromCharCode(number)
    }
  },
}

export let evalCtx = {
  SIN: Math.sin,

}

Object.keys(COMMON_FUNS).forEach(key => {
  evalCtx = Object.assign(evalCtx, COMMON_FUNS[key])
})

globalThis.__evalCtx__ = evalCtx
globalThis.evalGOGetFuns = function (label) {
  let keys = Object.keys(COMMON_FUNS[label])
  // console.log(keys)
  return keys.map(key => {
    return {
      label: key,
      value: key,
      notice: ZY.getHereDoc(COMMON_FUNS[label][key])
    }
  })
}

/**
 *
 * @param str
 * @param ctx
 * @returns {*}
 */
export function evalStr(str, ctx = {}) {
  return  ZY_EXT.eval5(str, {
    ...evalCtx,
    ...ctx
  })
}
